//
//  YLReqest.m
//  DoulinClient
//
//  Created by YLKJ on 2019/2/27.
//

#import "YLReqest.h"
#import "JSONMgr.h"
//加密
#import "SSKeyChainMgr.h"
#import "RSAMgr.h"
#import "NSData+YYAdd.h"
#import "NSData+XPAES128.h"
#import "BaseViewController.h"
#import "LoginPageViewController.h"

#pragma mark - ------------------ 普通网络请求 ------------------

@interface YLReqest ()

@property (nonatomic, copy) NSString * reqUrl;
@property (nonatomic, assign) BOOL hasHeader;
@property (nonatomic, assign) BOOL useCache;
@property (nonatomic, assign) BOOL isPost;
@property (nonatomic, assign) NSTimeInterval timeout;
@property (nonatomic, copy)   NSString *cmd;
@property (nonatomic, strong) NSDictionary *oriParam;//用于存储缓存的key
@property (nonatomic, strong) NSDictionary *param;

@end

@implementation  YLReqest
/** 加密参数, 有 HTTP 请求头, 不用缓存, 默认 10 秒超时 */
+ (instancetype)reqEncryptAndHeaderParam:(NSMutableDictionary *)param UrlString:(NSString*)url{
     [param setObject:@"1" forKey:@"type"];
     NSDictionary *dic = [[NSDictionary alloc] initWithDictionary:param];
    
     return [[self alloc] initWithURL:url encrypt:YES header:YES param:dic timeout:30 cache:NO];
}

+ (instancetype)reqNOEncryptAndHeaderParam:(NSMutableDictionary *)param UrlString:(NSString *)url{
    //type:1:商户 2:客户
      NSDictionary *dic = [[NSDictionary alloc] initWithDictionary:param];
      return [[self alloc] initWithURL:url encrypt:NO header:YES param:dic timeout:30 cache:NO];
}

/** 不加密参数, 有 HTTP 请求头, 不用缓存, 默认 10 秒超时 */
+ (instancetype)reqNoEncryptAndHeaderParam:(NSMutableDictionary *)param UrlString:(NSString*)url{
   //type:1:商户 2:客户
      [param setObject:@"1" forKey:@"type"];
       NSDictionary *dic = [[NSDictionary alloc] initWithDictionary:param];
       return [[self alloc] initWithURL:url encrypt:NO header:YES param:dic timeout:30 cache:NO];
}

- (instancetype)initWithURL:(NSString *)url encrypt:(BOOL)encrypt header:(BOOL)header param:(NSDictionary *)param timeout:(NSTimeInterval)timeout cache:(BOOL)cache{
    self = [super init];
    if (self){
        self.ignoreCache = cache;
        self.useCache = cache;
        self.reqUrl = url;
        NSLog(@"<-- %s, %d --> 👉👉👉👉👉👉reqUrl👈👈👈👈👈👈%@ 👉👉👉👉👉👉param👈👈👈👈👈👈%@", __FUNCTION__, __LINE__, url, param);
        self.oriParam = param?param:@{};
        if (param.count > 0) {
            self.cmd = param[@"password"]?param[@"password"]:@"";
            if (encrypt) {
                self.param = [self encryptParams:param];
                if(self.param == nil){
                self.tag = 1;
                } else {
                self.tag = 0;
               }
            } else {
            self.param = [self noEncryptParams:param];
            }
        } else {
            self.param = [self noEncryptParams:param];
        }
        self.hasHeader = header;
        self.timeout = timeout;
    }
    return self;
}

- (id)requestArgument{
    return _param;
}

- (nullable id)reqOriID {
    return _oriParam;
}

- (NSString *)requestUrl{
    return _reqUrl;
}

- (NSInteger)cacheTimeInSeconds{
    if (_useCache){
        return 60 * 60 * 24;
    } else {
        return -1;
    }
}

- (YTKRequestMethod)requestMethod {
    return  YTKRequestMethodPOST;
}

- (NSTimeInterval)requestTimeoutInterval {
    return _timeout;
}

- (NSDictionary<NSString *,NSString *> *)requestHeaderFieldValueDictionary {
    if (self.hasHeader) {
        @synchronized (self) {
            NSMutableDictionary *header = [@{} mutableCopy];
            YLUserInfo *InfoModel = [YLUserMgr fetchUser];
            if ([[[MSStorageUtils shareInstance] userDefaultGet:USER_DEFAULT_KEY_MEMBER_IsLogin] isEqualToString:@"YES"]) {
               // [params setObject:InfoModel.token forKey:@"account_token"];
                header[@"Authorization"] = [NSString stringWithFormat:@"Bearer %@",InfoModel.authorization];
            } else {
                header[@"Authorization"] = @"Basic dGVzdDp0ZXN0";
            }
            header[@"appVersion"] = @"1.0.0";   //版本号
//            header[@"device"] = @"iOS";
              NSLog(@"<-- %s, %d --> 🐔header🐔%@", __FUNCTION__, __LINE__, header);
              return header;
        }
    } else {
        return nil;
    }
}

- (YTKRequestSerializerType)requestSerializerType {
    return YTKRequestSerializerTypeHTTP;
}

- (YTKResponseSerializerType)responseSerializerType {
    return YTKResponseSerializerTypeHTTP;
}



@end


#pragma mark - ------------------ file上传 ------------------
@implementation YLUploadMedia

+ (instancetype)mediaWithType:(YLUploadMediaType)mediaType mediaName:(NSString *)mediaName mimeName:(NSString *)mimeName obj:(id)obj {
    return [[self alloc] initWithType:mediaType mediaName:mediaName mimeName:mimeName obj:obj];
}

- (instancetype)initWithType:(YLUploadMediaType)mediaType mediaName:(NSString *)mediaName mimeName:(NSString *)mimeName obj:(id)obj {
    if (self = [super init]) {
        self.mediaType = mediaType;
        self.mediaName = mediaName;
        self.mimeName = mimeName;
        self.obj = obj;
    }
    return self;
}

@end

@interface YLUploadRequest ()
@property (nonatomic, copy) NSString *reqUrl;
@property (nonatomic, strong) NSArray *files;
@property (nonatomic, strong) NSDictionary *param;

@end

@implementation YLUploadRequest

+ (instancetype)uploadFileReqUrl:(NSString *)Url param:(NSDictionary *)param files:(NSArray*)files{
    return [[self alloc]  initWithReqUrl:Url param:param files:files];
}

- (instancetype)initWithReqUrl:(NSString *)Url param:(NSDictionary *)param files:(NSArray *)files {
    self = [super init];
    if (self) {
        self.ignoreCache = YES;
        self.reqUrl = Url;
        self.files = files;
        self.param = param;
        NSLog(@"<-- %s, %d --> 👉👉👉👉👉👉param👈👈👈👈👈👈%@", __FUNCTION__, __LINE__, param);
    }
    return self;
}

- (id)requestArgument {
    return _param;
}

- (NSString *)requestUrl {
    return _reqUrl;
}

- (YTKRequestMethod)requestMethod {
    return YTKRequestMethodPOST;
}

- (NSTimeInterval)requestTimeoutInterval {
    return 30;
}

- (AFConstructingBlock)constructingBodyBlock {
    WeakSelf(self)
    return ^(id<AFMultipartFormData> formData) {
        StrongSelf(self)
        for (YLUploadMedia *media in self.files) {
            NSData *data;
            switch (media.mediaType) {
                case YLUploadMediaTypeJpg: {
                    if ([media.obj isKindOfClass:NSString.class]) {
                        UIImage * img = [UIImage imageWithContentsOfFile:media.obj];
                        data = UIImageJPEGRepresentation(img, 1);
                        if (data) {
                            [formData appendPartWithFileData:data name:media.mimeName fileName:media.mediaName?media.mediaName:@"test.jpg" mimeType:@"image/jpg"];
                        }
                    } else if ([media.obj isKindOfClass:UIImage.class]) {
                        data = UIImageJPEGRepresentation(media.obj, 1);
                        if (data) {
                            [formData appendPartWithFileData:data name:media.mimeName fileName:media.mediaName?media.mediaName:@"test.jpg" mimeType:@"image/jpg"];
                        }
                    }
                }
                break;
                case YLUploadMediaTypeAmr: {
                  if ([media.obj isKindOfClass:NSString.class]) {
                        NSURL *url = [NSURL fileURLWithPath:media.obj];
                        data = [NSData dataWithContentsOfFile:url.path];
                        if (data) {
                            [formData appendPartWithFileData:data name:media.mimeName fileName:media.mediaName?media.mediaName:@"test.amr" mimeType:@"audio/amr"];
                        }
                    }
                }
                    break;
                case YLUploadMediaTypeMp4: {
                    if ([media.obj isKindOfClass:NSString.class]) {
                        NSURL *url = [NSURL fileURLWithPath:media.obj];
                        data = [NSData dataWithContentsOfFile:url.path];
                        if (data) {
                            [formData appendPartWithFileData:data name:media.mimeName fileName:media.mediaName?media.mediaName:@"test.mp4" mimeType:@"video/mp4"];
                        }
                    }
                }
                    break;
            }
        }
    };
}

- (NSDictionary<NSString *,NSString *> *)requestHeaderFieldValueDictionary {
    @synchronized (self) {
        NSMutableDictionary *header = [@{} mutableCopy];
        YLUserInfo *InfoModel = [YLUserMgr fetchUser];
        if ([[[MSStorageUtils shareInstance] userDefaultGet:USER_DEFAULT_KEY_MEMBER_IsLogin] isEqualToString:@"YES"]) {
            // [params setObject:InfoModel.token forKey:@"account_token"];
            header[@"Authorization"] = [NSString stringWithFormat:@"Bearer %@",InfoModel.authorization];
        } else {
            header[@"Authorization"] = @"Basic dGVzdDp0ZXN0";
        }
        header[@"appVersion"] = @"";   //版本号
//        header[@"device"] = @"iOS";
        NSLog(@"<-- %s, %d --> 🐔header🐔%@", __FUNCTION__, __LINE__, header);
        return header;
    }
}

- (YTKRequestSerializerType)requestSerializerType{
    return YTKRequestSerializerTypeHTTP;
}

- (YTKResponseSerializerType)responseSerializerType {
    return YTKResponseSerializerTypeHTTP;
}

@end


#pragma mark - ------------------ 加密 ------------------
@implementation YTKRequest (Encrypt)
- (NSDictionary *)encryptParams:(id)params {
    if (params == nil){
        params = @{};
    }
    //key
    NSString * rsaKey = [SSKeyChainMgr getRSAKey];
    //NSLog(@"<-- %s, %d --> 公钥:%@", __FUNCTION__, __LINE__, rsaKey);
    NSString * aesKey = [SSKeyChainMgr getAESKey];
    //NSLog(@"<-- %s, %d --> AES-key:%@", __FUNCTION__, __LINE__, aesKey);
    
    //使用RSA加密AES的key
    NSString * rsaAesKey = [RSAMgr encryptString:aesKey publicKey:rsaKey];
    //NSLog(@"<-- %s, %d --> RSA加密key:%@", __FUNCTION__, __LINE__, rsaAesKey);
    
    //使用AES加密请求数据
    NSString * reqStr = [JSONMgr jsonStringFromObj:params];
    //NSLog(@"<-- %s, %d --> 请求数据:%@", __FUNCTION__, __LINE__, reqStr);
    NSData * reqData = [reqStr dataUsingEncoding:NSUTF8StringEncoding];
    NSData * reqDataAes = [reqData AES128EncryptWithKey:aesKey iv:aesKey];
    NSString * reqStrAes = [reqDataAes base64EncodedString];
    //NSLog(@"<-- %s, %d --> AES加密请求数据:%@", __FUNCTION__, __LINE__, reqStrAes);

    if ((rsaAesKey.length <= 0) || (reqStrAes.length <= 0)) {
        return nil;
    }
    NSMutableDictionary * paramDic = @{@"ak":rsaAesKey,@"ct":reqStrAes}.mutableCopy;
    NSMutableString * resultStr = [[NSMutableString alloc] initWithString:[JSONMgr jsonStringFromObj:paramDic]];
    //NSLog(@"<-- %s, %d --> %@", __FUNCTION__, __LINE__, resultStr);
    if (resultStr.length <= 0) {
        return nil;
    }
    NSDictionary * dic = @{@"json":[resultStr stringByReplacingOccurrencesOfString:@"\\" withString:@""]};
    //NSLog(@"<-- %s, %d --> 🐔🐔%@", __FUNCTION__, __LINE__, dic);
    
#if 0  //本地使用AES解密验证一下
    NSData * deAesData = [[NSData alloc] initWithBase64EncodedString:reqStrAes options:NSDataBase64DecodingIgnoreUnknownCharacters];
    deAesData = [deAesData AES128DecryptWithKey:aesKey iv:aesKey];
    NSString * deDataStr = [[NSString alloc] initWithData:deAesData encoding:NSUTF8StringEncoding];
    NSLog(@"<-- %s, %d --> AES解密: %@", __FUNCTION__, __LINE__, deDataStr);
#endif
    return dic;
}

- (NSDictionary *)noEncryptParams:(id)params {
    if (params == nil){
        params = @{};
    }
    NSMutableString *resultStr = [[NSMutableString alloc] initWithString:[JSONMgr jsonStringFromObj:params]];
    //NSLog(@"<-- %s, %d --> %@", __FUNCTION__, __LINE__, resultStr);
    if (resultStr.length <= 0) {
        return nil;
    }
    NSDictionary *dic = @{@"json":[resultStr stringByReplacingOccurrencesOfString:@"\\" withString:@""]};
    
    //NSLog(@"<-- %s, %d --> 🐔🐔%@", __FUNCTION__, __LINE__, dic);
    return dic;
}

@end

